/**create by framework at 2019年05月30日 15:47:03**/
package com.star.truffle.module.fzjz.service;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.star.truffle.common.constants.EnabledEnum;
import com.star.truffle.core.StarServiceException;
import com.star.truffle.core.jackson.StarJson;
import com.star.truffle.core.security.dto.StarUserInfo;
import com.star.truffle.core.security.dto.UserInfo;
import com.star.truffle.core.web.ApiCode;
import com.star.truffle.core.web.service.BaseService;
import com.star.truffle.module.fzjz.cache.PictureInfoCache;
import com.star.truffle.module.fzjz.cache.WarCategoryCache;
import com.star.truffle.module.fzjz.cache.WarInfoCache;
import com.star.truffle.module.fzjz.constant.PictureBusinessEnum;
import com.star.truffle.module.fzjz.domain.FzjzUserInfo;
import com.star.truffle.module.fzjz.domain.PictureInfo;
import com.star.truffle.module.fzjz.dto.req.WarInfoRequestDto;
import com.star.truffle.module.fzjz.dto.res.WarCategoryResponseDto;
import com.star.truffle.module.fzjz.dto.res.WarInfoResponseDto;

@Service
public class WarInfoService extends BaseService {

  @Autowired
  private StarJson starJson;
  @Autowired
  private WarInfoCache warInfoCache;
  @Autowired
  private WarCategoryCache warCategoryCache;
  @Autowired
  private PictureInfoCache pictureInfoCache;

  public Long saveWarInfo(WarInfoRequestDto warInfo) {
    StarUserInfo user = getLoginInfo(null);
    List<UserInfo> userInfos = user.getUserInfos();
    int areaId = 1;
    if(null != userInfos && ! userInfos.isEmpty()) {
      UserInfo userInfo = userInfos.get(0);
      Object ui = userInfo.getUserInfo();
      if(null != ui && ui instanceof FzjzUserInfo) {
        FzjzUserInfo fui = (FzjzUserInfo) ui;
        areaId = fui.getAreaId();
      }
    }
    warInfo.setCreateTime(new Date());
    warInfo.setCreateUser(user.getUsername());
    warInfo.setUpdateTime(warInfo.getCreateTime());
    warInfo.setUpdateUser(warInfo.getCreateUser());
    warInfo.setEnabled(EnabledEnum.enabled.val());
    warInfo.setAreaId(areaId);
    if(null == warInfo.getZoom()) {
      warInfo.setZoom(10);
    }
    this.warInfoCache.saveWarInfo(warInfo);
    if(null != warInfo.getPictures() && ! warInfo.getPictures().isEmpty()) {
      warInfo.setPictures(warInfo.getPictures().stream().filter(pic -> StringUtils.isNotBlank(pic.getUrl())).collect(Collectors.toList()));
      this.pictureInfoCache.batchSavePicture(PictureBusinessEnum.zzt.getBusiness(), warInfo.getId(), warInfo.getPictures());
    }
    return warInfo.getId();
  }

  public void updateWarInfo(WarInfoRequestDto warInfoRequestDto) {
    this.warInfoCache.updateWarInfo(warInfoRequestDto);
    this.pictureInfoCache.deleteByBusiness(PictureBusinessEnum.zzt.getBusiness(), warInfoRequestDto.getId());
    if(null != warInfoRequestDto.getPictures() && ! warInfoRequestDto.getPictures().isEmpty()) {
      this.pictureInfoCache.batchSavePicture(PictureBusinessEnum.zzt.getBusiness(), warInfoRequestDto.getId(), warInfoRequestDto.getPictures());
    }
  }

  public void deleteWarInfo(Long id) {
    this.warInfoCache.deleteWarInfo(id);
  }

  public void deleteWarInfo(String idstr) {
    if (StringUtils.isBlank(idstr)) {
      throw new StarServiceException(ApiCode.PARAM_ERROR);
    }
    String[] ids = idstr.split(",");
    for (String str : ids) {
      Long id = Long.parseLong(str);
      WarInfoRequestDto dto = new WarInfoRequestDto();
      dto.setId(id);
      dto.setEnabled(EnabledEnum.disabled.val());
      dto.setUpdateTime(new Date());
      dto.setUpdateUser(getLoginInfo(null).getUsername());
      this.warInfoCache.updateWarInfo(dto);
    }
  }

  public WarInfoResponseDto getWarInfo(Long id) {
    WarInfoResponseDto warInfoResponseDto = this.warInfoCache.getWarInfo(id);
    if(null != warInfoResponseDto) {
      WarCategoryResponseDto cate = this.warCategoryCache.getWarCategory(warInfoResponseDto.getCateId());
      List<String> fields = cate.getFields();
      Map<String, Object> infos = warInfoResponseDto.getInfos();
      Map<String, Object> validInfos = Collections.synchronizedMap(new LinkedHashMap<>());
      fields.stream().forEach(field -> {
        validInfos.put(field, null == infos || null == infos.get(field) ? "" : infos.get(field));
      });
      warInfoResponseDto.setInfos(validInfos);
      warInfoResponseDto.setPictures(this.pictureInfoCache.getByBusiness(PictureBusinessEnum.zzt.getBusiness(), id));
      
      if(null != warInfoResponseDto.getStations() && ! warInfoResponseDto.getStations().isEmpty()) {
        warInfoResponseDto.setStationNames(warInfoResponseDto.getStations().stream().collect(Collectors.joining(",")));
      }
    }
    return warInfoResponseDto;
  }

  public List<Map<String, Object>> queryWarInfoForMap(WarInfoRequestDto warInfoRequestDto) {
    if(StringUtils.isNotBlank(warInfoRequestDto.getSearchField()) && StringUtils.isNotBlank(warInfoRequestDto.getSearchValue())) {
      switch (warInfoRequestDto.getSearchField()) {
      case "id":
        try {
          warInfoRequestDto.setId(Long.valueOf(warInfoRequestDto.getSearchValue()));
        }catch(NumberFormatException e) {
          warInfoRequestDto.setId(-1L);
        }
        warInfoRequestDto.setSearchField(null);
        warInfoRequestDto.setSearchValue(null);
        break;
      case "lng":
        warInfoRequestDto.setLng(warInfoRequestDto.getSearchValue());
        warInfoRequestDto.setSearchField(null);
        warInfoRequestDto.setSearchValue(null);
        break;
      case "lat":
        warInfoRequestDto.setLat(warInfoRequestDto.getSearchValue());
        warInfoRequestDto.setSearchField(null);
        warInfoRequestDto.setSearchValue(null);
        break;
      default:
//        warInfoRequestDto.setSearchValue("(infos->'$.\""+warInfoRequestDto.getSearchField()+"\"') = \""+warInfoRequestDto.getSearchValue()+"\"");
        break;
      }
    }
    Map<Long, WarCategoryResponseDto> cates = Collections.synchronizedMap(new HashMap<>());
    if(null != warInfoRequestDto.getCateId()) {
      cates.put(warInfoRequestDto.getCateId(), this.warCategoryCache.getWarCategory(warInfoRequestDto.getCateId()));
    }
    warInfoRequestDto.setEnabled(EnabledEnum.enabled.val());
    List<WarInfoResponseDto> list = this.warInfoCache.queryWarInfo(warInfoRequestDto);
    List<Map<String, Object>> wars = list.stream().map(dto -> {
      WarCategoryResponseDto cate = cates.get(dto.getCateId());
      if(null == cate) {
        cate = this.warCategoryCache.getWarCategory(warInfoRequestDto.getCateId());
        cates.put(dto.getCateId(), cate);
      }
      if(null != cate) {
        dto.setIcon(cate.getIcon());
        dto.setOverIcon(cate.getOverIcon());
        dto.setCateName(cate.getName());
      }
      Map<String, Object> infos = dto.getInfos();
      Map<String, Object> record = starJson.bean2Map(dto);
      record.remove("infos");
      if(null != infos) {
        record.putAll(infos);
      }
      return record;
    }).collect(Collectors.toList());
    return wars;
  }
  
  public List<WarInfoResponseDto> queryWarInfo(WarInfoRequestDto warInfoRequestDto) {
    Map<Long, WarCategoryResponseDto> cates = Collections.synchronizedMap(new HashMap<>());
    if(null != warInfoRequestDto.getCateId()) {
      cates.put(warInfoRequestDto.getCateId(), this.warCategoryCache.getWarCategory(warInfoRequestDto.getCateId()));
    }
    warInfoRequestDto.setEnabled(EnabledEnum.enabled.val());
    List<WarInfoResponseDto> list = this.warInfoCache.queryWarInfo(warInfoRequestDto);
    list.stream().forEach(dto -> {
      WarCategoryResponseDto cate = cates.get(dto.getCateId());
      if(null == cate) {
        cate = this.warCategoryCache.getWarCategory(warInfoRequestDto.getCateId());
        cates.put(dto.getCateId(), cate);
      }
      if(null != cate) {
        dto.setCateType(cate.getType());
        dto.setIcon(cate.getIcon());
        dto.setOverIcon(cate.getOverIcon());
        dto.setCateName(cate.getName());
        if(cate.getType() == 2) {
          List<PictureInfo> pictures = this.pictureInfoCache.getByBusiness(PictureBusinessEnum.zzt.getBusiness(), dto.getId());
          dto.setPictures(pictures);
        }
      }
    });
    return list;
  }

  public Long queryWarInfoCount(WarInfoRequestDto warInfoRequestDto) {
    if(StringUtils.isNotBlank(warInfoRequestDto.getSearchField()) && StringUtils.isNotBlank(warInfoRequestDto.getSearchValue())) {
      switch (warInfoRequestDto.getSearchField()) {
      case "id":
        try {
          warInfoRequestDto.setId(Long.valueOf(warInfoRequestDto.getSearchValue()));
        }catch(NumberFormatException e) {
          warInfoRequestDto.setId(-1L);
        }
        warInfoRequestDto.setSearchField(null);
        warInfoRequestDto.setSearchValue(null);
        break;
      case "lng":
        warInfoRequestDto.setLng(warInfoRequestDto.getSearchValue());
        warInfoRequestDto.setSearchField(null);
        warInfoRequestDto.setSearchValue(null);
        break;
      case "lat":
        warInfoRequestDto.setLat(warInfoRequestDto.getSearchValue());
        warInfoRequestDto.setSearchField(null);
        warInfoRequestDto.setSearchValue(null);
        break;
      default:
        warInfoRequestDto.setSearchValue("(infos->'$.\""+warInfoRequestDto.getSearchField()+"\"') = \""+warInfoRequestDto.getSearchValue()+"\"");
        break;
      }
    }
    warInfoRequestDto.setEnabled(EnabledEnum.enabled.val());
    return this.warInfoCache.queryWarInfoCount(warInfoRequestDto);
  }

  public void delDatas(Long cateId) {
    WarInfoRequestDto dto = new WarInfoRequestDto();
    dto.setCateId(cateId);
    this.warInfoCache.delDatas(dto);
  }

  public void saveWarInfos(Long cateId, List<WarInfoRequestDto> warInfos) {
    delDatas(cateId);
    if(null != warInfos && ! warInfos.isEmpty()) {
      warInfos.forEach(war -> {
        this.saveWarInfo(war);
      });
    }
  }

}